package service;

import dao.SongDao;
import dao.UserDao;
import dao.CurrentPlaylistDao;
import entity.Song;
import util.EntityConverter;
import util.ResponseUtil;
import util.ValidationUtil;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.charset.StandardCharsets;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;
import java.sql.Connection;
import util.DatabaseUtil;

public class MusicService {
    private final SongDao songDao;
    private final UserDao userDao;
    private final CurrentPlaylistDao currentPlaylistDao;
    
    public MusicService() {
        this.songDao = new SongDao();
        this.userDao = new UserDao();
        this.currentPlaylistDao = new CurrentPlaylistDao();
    }
    
    public Map<String, Object> getCurrentPlaylist(Long userId) {
        try {
            List<Song> songs = songDao.findPlaylistByUserId(userId);
            List<Map<String, Object>> playlist = songs.stream()
                .map(EntityConverter::songToMap)
                .collect(Collectors.toList());
            
            return ResponseUtil.success(playlist);
            
        } catch (SQLException e) {
            e.printStackTrace();
            return ResponseUtil.error("获取播放列表失败");
        }
    }
    
    public Map<String, Object> getRecentPlays(Long userId) {
        try {
            List<Song> songs = songDao.findRecentPlaysByUserId(userId);
            List<Map<String, Object>> recentMusic = songs.stream()
                .map(EntityConverter::songToMap)
                .collect(Collectors.toList());
            
            return ResponseUtil.success(recentMusic);
            
        } catch (SQLException e) {
            e.printStackTrace();
            return ResponseUtil.error("获取最近播放失败");
        }
    }
    
    public Map<String, Object> getHotMusic() {
        try {
            List<Song> songs = songDao.findHotSongs(10);
            List<Map<String, Object>> hotMusic = songs.stream()
                .map(EntityConverter::songToMap)
                .collect(Collectors.toList());
            
            return ResponseUtil.success(hotMusic);
            
        } catch (SQLException e) {
            e.printStackTrace();
            return ResponseUtil.error("获取热门音乐失败");
        }
    }
    
    public Map<String, Object> getMusicById(String id) {
        try {
            Song song = songDao.findById(Long.parseLong(id));
            if (song == null) {
                return ResponseUtil.error("音乐不存在");
            }
            
            return ResponseUtil.success(EntityConverter.songToMap(song));
            
        } catch (SQLException e) {
            e.printStackTrace();
            return ResponseUtil.error("获取音乐详情失败");
        }
    }
    
    public Map<String, Object> getMusicCover(String id) {
        try {
            Song song = songDao.findById(Long.parseLong(id));
            if (song == null) {
                return ResponseUtil.error("音乐不存在");
            }
            
            Map<String, Object> data = new HashMap<>();
            data.put("url", "/" + song.getCoverFilePath());
            return ResponseUtil.success(data);
            
        } catch (SQLException e) {
            e.printStackTrace();
            return ResponseUtil.error("获取音乐封面失败");
        }
    }
    
    public Map<String, Object> getMusicLyric(String id) {
        try {
            Song song = songDao.findById(Long.parseLong(id));
            if (song == null) {
                return ResponseUtil.error("音乐不存在");
            }
            
            String lyricContent = new String(Files.readAllBytes(Paths.get(song.getLyricFilePath())), StandardCharsets.UTF_8);
            Map<String, Object> data = new HashMap<>();
            data.put("lyric", lyricContent);
            return ResponseUtil.success(data);
            
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseUtil.error("获取歌词失败");
        }
    }
    
    public Map<String, Object> getMusicSource(String id) {
        try {
            Song song = songDao.findById(Long.parseLong(id));
            if (song == null) {
                return ResponseUtil.error("音乐不存在");
            }
            
            Map<String, Object> data = new HashMap<>();
            data.put("url", "/" + song.getMusicFilePath());
            data.put("token", "dummy-token");
            data.put("expires", System.currentTimeMillis() + 3600000);
            data.put("bitrate", 320000);
            data.put("format", "mp3");
            
            return ResponseUtil.success(data);
            
        } catch (SQLException e) {
            e.printStackTrace();
            return ResponseUtil.error("获取音乐源文件失败");
        }
    }
    
    public Map<String, Object> addToRecentPlays(Long userId, Long songId) {
        try {
            // 获取最近播放的歌曲列表
            List<Song> recentSongs = songDao.findRecentPlaysByUserId(userId);
            
            // 找到当前歌曲在最近播放中的位置（如果存在）
            int currentIndex = -1;
            for (int i = 0; i < recentSongs.size(); i++) {
                if (recentSongs.get(i).getSongId().equals(songId)) {
                    currentIndex = i;
                    break;
                }
            }
            
            // 开启事务
            Connection conn = DatabaseUtil.getConnection();
            conn.setAutoCommit(false);
            
            try {
                if (currentIndex != -1) {
                    // 如果歌曲已存在于最近播放列表中
                    // 保存需要移动的歌曲
                    List<Song> songsToMove = recentSongs.subList(0, currentIndex);
                    
                    // 删除所有需要移动的歌曲（包括当前歌曲）
                    for (Song song : songsToMove) {
                        songDao.removeFromRecentPlays(userId, song.getSongId());
                    }
                    songDao.removeFromRecentPlays(userId, songId);
                    
                    // 重新插入这些歌曲，位置+1
                    int position = 2; // 从位置2开始，因为当前歌曲要放在位置1
                    for (Song song : songsToMove) {
                        songDao.addToRecentPlaysWithPosition(userId, song.getSongId(), position++);
                    }
                } else {
                    // 如果歌曲不在最近播放列表中
                    if (recentSongs.size() >= 5) {
                        // 删除最后一首歌
                        songDao.removeFromRecentPlays(userId, recentSongs.get(4).getSongId());
                    }
                    
                    // 保存前4首歌
                    List<Song> songsToMove = recentSongs.subList(0, Math.min(4, recentSongs.size()));
                    
                    // 删除这些歌
                    for (Song song : songsToMove) {
                        songDao.removeFromRecentPlays(userId, song.getSongId());
                    }
                    
                    // 重新插入这些歌，位置+1
                    int position = 2; // 从位置2开始
                    for (Song song : songsToMove) {
                        songDao.addToRecentPlaysWithPosition(userId, song.getSongId(), position++);
                    }
                }
                
                // 将新歌曲插入到第一位
                songDao.addToRecentPlaysWithPosition(userId, songId, 1);
                
                conn.commit();
                return ResponseUtil.success("播放记录已更新");
                
            } catch (Exception e) {
                conn.rollback();
                throw e;
            } finally {
                conn.setAutoCommit(true);
            }
            
        } catch (SQLException e) {
            e.printStackTrace();
            return ResponseUtil.error("更新播放记录失败");
        }
    }
    
    public Map<String, Object> updatePlayCount(Long songId) {
        try {
            songDao.incrementPlayCount(songId);
            return ResponseUtil.success("播放次数已更新");
        } catch (SQLException e) {
            e.printStackTrace();
            return ResponseUtil.error("更新播放次数失败");
        }
    }
    
    public Map<String, Object> searchMusic(String keyword) {
        try {
            List<Song> songs = songDao.searchSongs(keyword);
            List<Map<String, Object>> songList = songs.stream()
                .map(EntityConverter::songToMap)
                .collect(Collectors.toList());
            
            return ResponseUtil.success(songList);
            
        } catch (SQLException e) {
            e.printStackTrace();
            return ResponseUtil.error("搜索失败");
        }
    }
    
    public Map<String, Object> getSuggestions(String keyword) {
        try {
            List<Map<String, String>> suggestions = songDao.getSuggestions(keyword);
            return ResponseUtil.success(suggestions);
            
        } catch (SQLException e) {
            e.printStackTrace();
            return ResponseUtil.error("获取搜索建议失败");
        }
    }
    
    public Map<String, Object> getMusicLibrary(int page, int pageSize) {
        try {
            int total = songDao.count();
            List<Song> songs = songDao.findPage(page, pageSize);
            List<Map<String, Object>> musicList = songs.stream()
                .map(EntityConverter::songToMap)
                .collect(Collectors.toList());
            
            Map<String, Object> data = new HashMap<>();
            data.put("total", total);
            data.put("list", musicList);
            
            return ResponseUtil.success(data);
            
        } catch (SQLException e) {
            e.printStackTrace();
            return ResponseUtil.error("获取音乐库数据失败");
        }
    }
    
    public Map<String, Object> addToPlaylist(Long userId, Long musicId) {
        try {
            if (currentPlaylistDao.existsInPlaylist(userId, musicId)) {
                return ResponseUtil.success("歌曲已在播放列表中");
            }
            
            int newPosition = currentPlaylistDao.getMaxPosition(userId) + 1;
            currentPlaylistDao.addSongWithPosition(userId, musicId, newPosition);
            
            return ResponseUtil.success("添加成功");
            
        } catch (SQLException e) {
            e.printStackTrace();
            return ResponseUtil.error("添加失败: " + e.getMessage());
        }
    }
    
    public Map<String, Object> removeFromPlaylist(Long userId, Long songId) {
        try {
            currentPlaylistDao.removeSong(userId, songId);
            return ResponseUtil.success("移除成功");
        } catch (SQLException e) {
            e.printStackTrace();
            return ResponseUtil.error("移除失败");
        }
    }
    
    public Map<String, Object> clearPlaylist(Long userId) {
        try {
            currentPlaylistDao.clear(userId);
            return ResponseUtil.success("播放列表已清空");
        } catch (SQLException e) {
            e.printStackTrace();
            return ResponseUtil.error("清空播放列表失败");
        }
    }
} 